
#include "GravBody.h"

/*--------------------------------------------------------------------*/
void GravBody::init(int pID, Vec3f loc, Vec3f vel, float rad, float mass, float rotAxis, float rotInc) {

	rotationAxis = rotAxis;
	rotationInc = rotInc;
	ID = pID;
	vLoc = loc;
	oldLoc = loc;
	vVel = vel;
	fRad = rad;
	fMass = mass;
	fMassSqr = mass*mass;
	fInvMassSqr = 1/fMassSqr;
	maxDetail = 5;
	//gGeo = new Geosphere(fRad,maxDetail);
	historyTime = 0;
	curRotation = 0;


	//InitializeCriticalSection(&historyCS);
}

/*--------------------------------------------------------------------*/
void GravBody::init(int pID, Vec3f loc, Vec3f vel, float rad, float mass) {

	ID = pID;
	vLoc = loc;
	oldLoc = loc;
	vVel = vel;
	fRad = rad;
	fMass = mass;
	fMassSqr = mass*mass;
	fInvMassSqr = 1/fMassSqr;
	maxDetail = 5;
	//gGeo = new Geosphere(fRad,maxDetail);
	historyTime = 0;
	rotationInc = rotationAxis = 0;
	curRotation = 0;


	//InitializeCriticalSection(&historyCS);
}


/*--------------------------------------------------------------------*/
void GravBody::updateWithForce(Vec3f f, float timeScale) {
	vVel += f;
	oldLoc = vLoc;
	vLoc += vVel*timeScale;	
}

/*--------------------------------------------------------------------*/
void GravBody::updateHistory(float timePass) {
	historyTime += timePass;
	if ( historyTime > 100 ) { 
		history.push_front(vLoc);
		historyTime = 0;
	}

	// Block this section with a semaphore
	//getHistoryAccess(true);

	// Remember ten seconds worth of history
	if ( history.size() > 100 ) { history.pop_back(); }

	//getHistoryAccess(false);
}

/*--------------------------------------------------------------------*/
void GravBody::updateFuture(Vec3f f, float timePass) {
	
	Vec3f tempLoc = vLoc;
	Vec3f tempVel = vVel;

	//empty the list
	future.clear();

	future.push_back(tempLoc);

	//get 25 future points based up current force and velocity
	for (int i = 0; i < 25; ++i) {		
		tempVel += f;
		tempLoc += tempVel*timePass*5;
		future.push_back(tempLoc);
	}

}

/*--------------------------------------------------------------------*/
void GravBody::updateRotation(float timePass) {
	//update the rotation
	curRotation += rotationInc*timePass;
}

/*--------------------------------------------------------------------*/
const Vec3f* GravBody::getLoc() { return &vLoc; }
const Vec3f* GravBody::getOldLoc() { return &oldLoc; }
const Vec3f* GravBody::getVel() { return &vVel; }
const Vec3f* GravBody::getForce() { return &force; }
const int GravBody::getID() { return ID; }
const float GravBody::getRad() { return fRad; }
const float GravBody::getMass() { return fMass; }
const float GravBody::getMassSqr() { return fMassSqr; }
const float GravBody::getInvMassSqr() { return fInvMassSqr; }
const int GravBody::getMaxDetail() { return maxDetail; }
const list<Vec3f>* GravBody::getHistory() { return &history; }
const list<Vec3f>* GravBody::getFuture() { return &future; }
//Geosphere* GravBody::getGeosphere() { return gGeo; }
float GravBody::getRotationAxis() { return rotationAxis; }
float GravBody::getCurRotation() { return curRotation; }

/*--------------------------------------------------------------------*/
void GravBody::setVel(Vec3f* vel) { vVel = *vel; }

/*--------------------------------------------------------------------*/
void GravBody::setLoc(Vec3f* loc) { oldLoc = vLoc;  vLoc = *loc; }

/*--------------------------------------------------------------------*/
void GravBody::setForce(Vec3f* f) {force = *f; }

/*--------------------------------------------------------------------*/
void GravBody::acceptMass(GravBody* g) { fMass += g->getMass(); }

/*--------------------------------------------------------------------*/
Vec3f GravBody::getGfxLoc() { return vLoc; }

/*--------------------------------------------------------------------*/
//void GravBody::alterTerrain() { gGeo->buildTerrain(); }

/*--------------------------------------------------------------------*/
/*void GravBody::getHistoryAccess(bool enter) {
	enter ? 
		EnterCriticalSection(&historyCS) : 
		LeaveCriticalSection(&historyCS);
}*/

/*--------------------------------------------------------------------*/
void GravBody::clearHistory() {
	history.clear();
}

